package server

import (
	"chatServer/src/jsonEntity"
	"sync"
	"time"
)

const (
	//MaxMsgLen 房间最大聊天消息数
	MaxMsgLen = 50
	//PopularResetTime 热度消息重置分钟
	PopularResetTime = 10
)

//ChatRoom 聊天房间结构
type ChatRoom struct {
	roomID         int
	roomName       string
	addUserChannel chan *User
	chatChannel    chan string
	userMap        map[string]*User
	msgQueue       []string
	msgMap         map[string]int
	userMapLock    sync.RWMutex
}

// createChatRoom 创建房间
func createChatRoom(conf jsonEntity.RoomConf) *ChatRoom {
	chatRoom := &ChatRoom{
		roomID:         conf.RoomID,
		roomName:       conf.RoomName,
		addUserChannel: make(chan *User),
		chatChannel:    make(chan string),
		userMap:        make(map[string]*User),
		msgQueue:       make([]string, MaxMsgLen+1),
		msgMap:         make(map[string]int)} // 为了不让切片扩容
	go chatRoom.listenChannel()
	return chatRoom
}

// 添加玩家进入房间
func (c *ChatRoom) addUser(user *User) {
	c.userMap[user.userName] = user
	msg := "[" + "系统" + "]: 用户 " + user.userName + " 进入房间"
	for _, value := range c.msgQueue {
		if value != "" {
			user.send2Client(value)
		}
	}
	c.broadCast(msg)
}

// 玩家退出房间删除玩家
func (c *ChatRoom) deleteUser(user *User) {
	c.userMapLock.Lock()
	defer c.userMapLock.Unlock()
	delete(c.userMap, user.userName)
	msg := "[" + "系统" + "]: 用户 " + user.userName + " 离开房间"
	c.broadCast(msg)
}

// 监听channel
func (c *ChatRoom) listenChannel() {
	for {
		select {
		case u := <-c.addUserChannel: // 玩家加入channel
			c.addUser(u)
			break
		case msg := <-c.chatChannel: // 消息发送channel
			c.sendMsg(msg)
			break
		case <-time.After(time.Minute * PopularResetTime):
			c.msgMap = make(map[string]int)
		}
	}
}

// 发送消息
func (c *ChatRoom) sendMsg(msg string) {
	if len(c.msgQueue) >= MaxMsgLen {
		c.msgQueue = c.msgQueue[1:]
	}
	c.msgQueue = append(c.msgQueue, msg)
	msgCount := c.msgMap[msg]
	msgCount++
	c.msgMap[msg] = msgCount
	c.broadCast(msg)
}

// 广播通知
func (c *ChatRoom) broadCast(msg string) {
	for _, user := range c.userMap {
		user.send2Client(msg)
	}
}

// 用户名修改
func (c *ChatRoom) userRename(oldName string, u *User) {
	c.userMapLock.Lock()
	defer c.userMapLock.Unlock()
	delete(c.userMap, oldName)
	c.userMap[u.userName] = u
}

//GetMsgMap 获取消息MAP
func (c *ChatRoom) GetMsgMap() map[string]int {
	return c.msgMap
}
